package com.gao.api.gate.quick.core.async;

import java.util.concurrent.Callable;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.FutureTask;

/**
 * <p></p>
 *
 * @author gaoshuangwen
 * @since 2022/01/12 10:14
 */
public class ListenableFutureTask<T> extends FutureTask<T> implements ListenableFuture<T> {

    private final ListenableFutureListenerRegistry<T> registry = new ListenableFutureListenerRegistry<>();


    public ListenableFutureTask(Callable<T> callable) {
        super(callable);
    }

    public ListenableFutureTask(Runnable runnable, T result) {
        super(runnable, result);
    }

    @Override
    protected void done() {
        Throwable cause;
        try {
            T result = get();
            this.registry.success(result);
            return;
        } catch (InterruptedException ex) {
            Thread.currentThread().interrupt();
            return;
        } catch (ExecutionException ex) {
            cause = ex.getCause();
            if (cause == null) {
                cause = ex;
            }
        } catch (Throwable ex) {
            cause = ex;
        }
        this.registry.failure(cause);
    }

    @Override
    public void addListener(Listener<T> listener) {
        registry.addNode(listener);
    }
    @Override
    public CompletableFuture<T> buildCompletableFuture(){
        CompletableFuture<T> completableFuture = new CompletableFuture<>();

        registry.addNode(new Listener<T>() {
            @Override
            public void onSuccess(T t) {
                completableFuture.complete(t);
            }

            @Override
            public void onFailure(Throwable ex) {
                completableFuture.completeExceptionally(ex);
            }
        });
        return completableFuture;
    }


}